﻿using BaseFramework;
using LiteFramework;
using LiteFramework.Server;
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Reflection;
using System.Web;
using System.Web.SessionState;

namespace Website.Action
{
    public abstract class BaseHttpHandler : IHttpHandler, IRequiresSessionState
    {
        /// <summary>
        /// 默认页面数据大小
        /// </summary>
        protected const int ___dafaultPageSize = 10;
        /// <summary>
        /// 当前会话上下文
        /// </summary>
        protected HttpContext __context = null;

        #region IHttpHandler 成员

        public void ProcessRequest(HttpContext context)
        {
            this.__context = context;
            context.Response.ContentType = this.responseContentType;

            // 身份认证
            if (this.reqiredAuthorized)
            {
#if !DEBUG
                //var result = this.validUser();
                //if (!result.ok)
                //{
                //    __context.Response.Write(this.formatResult(result));
                //    __context.Response.End();
                //}
#endif
            }

            string action = HttpHelper.GetRequestValue(context.Request, "action");
            if (action != null) action = action.ToLower().Trim();

            try
            {
                ActionStatus code = ActionStatus.ok;
                string err = null;
                if (!this.onDoAction(ref  action, out code, out err))
                {
                    __context.Response.Write(this.formatResult(ActionResult.Error(code, err)));
                    __context.Response.End();
                }
                ActionResult result = this.doAction(context, action);
                string responseString = this.formatResult(result);

                // 调试日志
                //ServerApplication.WriteLog("Debugging.Handler", ServerApplication.LogType.Info, string.Format("【Type】 {0}; 【Action】 {1}; 【Params】 {2}; 【Method】 {3}; 【IP】 {4}; 【Return】 {5}", this.GetType().Name, this.Action, this.__context.Request.QueryString + "&" + this.__context.Request.Form, this.HttpMethod, SystemResources.Host_Info, responseString));

                this.onReturnBacking(result);
                if (result != null)
                {
                    context.Response.Write(responseString);
                }
            }
            catch (Exception ex)
            {
                while (ex.InnerException != null)
                {
                    ex = ex.InnerException;
                }

                ServerApplication.WriteLog("Debugging.Handler", ServerApplication.LogType.Info, string.Format("【Type】 {0}; 【Action】 {1}; 【Params】 {2}; 【Method】 {3}; 【IP】 {4}; 【Return】 {5}", this.GetType().Name, this.Action, this.__context.Request.QueryString + "&" + this.__context.Request.Form, this.HttpMethod, SystemResources.Host_Info, this.formatResult(new ActionResult { status = ActionStatus.error, message = ex.Message })));

                context.Response.Write(this.formatResult(new ActionResult { status = ActionStatus.error, message = ex.Message }));
            }
        }

        public bool IsReusable { get { return false; } }

        #endregion

        #region 属性

        /// <summary>
        /// 动作（小写）
        /// </summary>
        protected string Action
        {
            get
            {
                /// 动作
                return this.__context != null ? HttpHelper.GetRequestValue(this.__context.Request, "Action", string.Empty).ToLower() : string.Empty;
            }
        }

        /// <summary>
        /// 传输方式（小写）
        /// </summary>
        protected string HttpMethod
        {
            get
            {
                /// 传输方式
                return this.__context != null ? this.__context.Request.HttpMethod.ToLower() : string.Empty;
            }
        }

        /// <summary>
        /// 用途（小写）。主要用于UI框架，如 useAt=Validform，useAt=DWZ，useAt=Option
        /// </summary>
        protected string UseAt
        {
            get
            {
                /// 用处。主要用于UI框架，如 useAt=Validform
                return this.__context != null ? HttpHelper.GetRequestValue(this.__context.Request, "UseAt", string.Empty).ToLower() : string.Empty;
            }
        }

        /// <summary>
        /// 请求来自页面
        /// </summary>
        protected string FromUrl
        {
            get
            {
                /// 请求来自页面
                return this.__context != null ? this.__context.Request.UrlReferrer.AbsoluteUri : string.Empty;
            }
        }

        /// <summary>
        /// 跳转页面
        /// </summary>
        protected string ForwardUrl
        {
            get
            {
                /// 跳转页面
                return this.__context != null ? HttpHelper.GetRequestValue(this.__context.Request, "ForwardUrl") : null;
            }
        }

        /// <summary>
        /// 是否不跳转
        /// </summary>
        protected bool NotJump
        {
            get
            {
                /// 是否不跳转
                return this.__context != null ? HttpHelper.GetRequestValue(this.__context.Request, "NotJump", false) : false;
            }
        }

        /// <summary>
        /// 是否验证超时
        /// </summary>
        protected virtual bool checkTimeout { get { return true; } }

        #endregion

        #region abstract
        /// <summary>
        /// 处理请求的方法
        /// </summary>
        /// <param name="context"></param>
        /// <param name="action"></param>
        protected abstract ActionResult doAction(HttpContext context, string action);
        #endregion

        #region virtual
        /// <summary>
        /// 需要身份认证
        /// </summary>
        protected virtual bool reqiredAuthorized { get { return true; } }
        /// <summary>
        /// 响应ContentType
        /// </summary>
        protected virtual string responseContentType { get { return "application/json"; } } // "text/plain"
        /// <summary>
        /// 格式化处理结果
        /// </summary>
        /// <param name="result"></param>
        /// <returns></returns>
        protected virtual string formatResult(ActionResult result)
        {
            if (result == null)
                return string.Empty;

            switch (this.UseAt)
            {
                case "validform":
                    return result.ToString_Validform();
                case "dwz":
                    return result.ToString_DWZ();
                default:
                    return result.ToString();
            }
        }
        /// <summary>
        /// 在执行doAction()方法前执行，可用于拦截/转发请求。
        /// 返回false，代表请求失败，需要返回err错误值
        /// </summary>
        /// <param name="action">请求的命令，允许被拦截并修改</param>
        /// <param name="code">方法返回false时的错误码</param>
        /// <param name="err">方法返回false时的错误信息</param>
        /// <returns></returns>
        protected virtual bool onDoAction(ref string action, out ActionStatus code, out string err)
        {
            code = ActionStatus.ok;
            err = null;
            return true;
        }
        /// <summary>
        /// 在答复请求时执行的方法 (doAction方法后执行)
        /// </summary>
        /// <param name="result"></param>
        protected virtual void onReturnBacking(ActionResult result) { }
        #endregion

        #region 方法

        /// <summary>
        /// 获取客户端的请求参数
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        protected string GetRequestValue(string key)
        {
            return this.GetRequestValue<string>(key, null);
        }
        /// <summary>
        /// 获取客户端的请求参数
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key"></param>
        /// <returns></returns>
        protected T GetRequestValue<T>(string key)
        {
            return this.GetRequestValue<T>(key, default(T));
        }
        /// <summary>
        /// 获取客户端的请求参数
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key"></param>
        /// <param name="defaultValue"></param>
        /// <returns></returns>
        protected T GetRequestValue<T>(string key, T defaultValue)
        {
            return this.__context != null ? HttpHelper.GetRequestValue<T>(this.__context.Request, key, defaultValue) : defaultValue;
        }

        /// <summary>
        /// 获取客户端的Get请求参数
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        protected string GetQueryValue(string key)
        {
            return this.GetQueryValue<string>(key, null);
        }
        /// <summary>
        /// 获取客户端的Get请求参数
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key"></param>
        /// <returns></returns>
        protected T GetQueryValue<T>(string key)
        {
            return this.GetQueryValue<T>(key, default(T));
        }
        /// <summary>
        /// 获取客户端的Get请求参数
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key"></param>
        /// <param name="defaultValue"></param>
        /// <returns></returns>
        protected T GetQueryValue<T>(string key, T defaultValue)
        {
            return this.__context != null ? HttpHelper.GetQueryValue<T>(this.__context.Request, key, defaultValue) : defaultValue;
        }

        /// <summary>
        /// 获取客户端的Post请求参数
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        protected string GetFormValue(string key)
        {
            return this.GetFormValue<string>(key, null);
        }
        /// <summary>
        /// 获取客户端的Post请求参数
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key"></param>
        /// <returns></returns>
        protected T GetFormValue<T>(string key)
        {
            return this.GetFormValue<T>(key, default(T));
        }
        /// <summary>
        /// 获取客户端的Post请求参数
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key"></param>
        /// <param name="defaultValue"></param>
        /// <returns></returns>
        protected T GetFormValue<T>(string key, T defaultValue)
        {
            return this.__context != null ? HttpHelper.GetFormValue<T>(this.__context.Request, key, defaultValue) : defaultValue;
        }

        /// <summary>
        /// 创建服务组件
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        protected T CreateComp<T>()
        {
            return ServerApplication.ComponentFactory.Create<T>();
        }

        #endregion

        #region AutoFillProperty
        /// <summary>
        /// 填充数据前执行，返回true将终止填充操作
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="obj"></param>
        /// <param name="propertyName"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        protected delegate bool FormatValueHandle<T>(T obj, string propertyName, object value);
        protected void AutoFillProperies<T>(T obj)
        {
            this._autoFillProperies<T>(obj, null, null, null, null);
        }
        protected void AutoFillProperies<T>(T obj, string[] fillProperties)
        {
            this._autoFillProperies<T>(obj, fillProperties, null, null, null);
        }
        protected void AutoFillProperies<T>(T obj, FormatValueHandle<T> formatValue)
        {
            this._autoFillProperies<T>(obj, null, null, formatValue, null);
        }
        /// <summary>
        /// 自动填充客户端请求的数据到对象T
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="obj"></param>
        /// <param name="fillProperties">指定【需要】填充的属性列表。为空时，默认为填充全部属性</param>
        /// <param name="unFillProperties">指定【不需要】填充的属性列表</param>
        /// <param name="formatValue">外部处理方法，填充前执行。返回true时，内部将不处理填充</param>
        /// <param name="initValue">外部处理方法，填充前执行。提交的表单中找不到同名键时执行</param>
        protected void AutoFillProperies<T>(T obj, string[] fillProperties, string[] unFillProperties, FormatValueHandle<T> formatValue, Action<T, string> initValue)
        {
            this._autoFillProperies<T>(obj, fillProperties, unFillProperties, formatValue, initValue);
        }
        /// <summary>
        /// 自动填充客户端请求的数据到对象T
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="obj"></param>
        /// <param name="fillProperties">指定【需要】填充的属性列表。为空时，默认为填充全部属性</param>
        /// <param name="unFillProperties">指定【不需要】填充的属性列表</param>
        /// <param name="formatValue">外部处理方法，填充前执行。返回true时，内部将不处理填充</param>
        /// <param name="initValue">外部处理方法，填充前执行。提交的表单中找不到同名键时执行</param>
        private void _autoFillProperies<T>(T obj, string[] fillProperties, string[] unFillProperties, FormatValueHandle<T> formatValue, Action<T, string> initValue)
        {
            if (obj != null)
            {
                PropertyInfo[] infos = obj.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.SetField | BindingFlags.SetProperty);
                if (infos != null)
                {
                    foreach (PropertyInfo info in infos)
                    {
                        #region needFill

                        ///
                        /// 1.初始化needFill为不需要填充
                        /// 2.遍历需要填充的列表(空时，默认为填充全部属性)，判断是否需要填充
                        /// 3.若，2中需要填充，遍历不需要填充的列表，判断是否不需要填充
                        /// 4.以上两次遍历，算出是否需要填充
                        /// 5.不需要填充，跳出本次大循环
                        ///
                        bool needFill = false; // 1.
                        if (fillProperties != null && fillProperties.Length > 0)
                        {
                            foreach (string fillProperty in fillProperties)
                            {
                                if (info.Name == fillProperty) // 2.
                                {
                                    needFill = true;
                                    break;
                                }
                            }
                        }
                        else
                        {
                            needFill = true; // 空，默认为填充全部属性
                        }

                        if (needFill && unFillProperties != null) // 3.
                        {
                            foreach (string unFillProperty in unFillProperties)
                            {
                                if (info.Name == unFillProperty) // 4.
                                {
                                    needFill = false;
                                    break;
                                }
                            }
                        }

                        if (!needFill) // 5.不需要填充
                            continue;

                        #endregion

                        string requestKey = info.Name;
                        bool esixtRequestKey = HttpHelper.ExistRequestKey(this.__context.Request, requestKey);

                        if (!esixtRequestKey)
                        {
                            if (info.PropertyType.IsSubclassOf(typeof(Bag)))
                            {
                                requestKey = info.Name + "ID";
                                esixtRequestKey = HttpHelper.ExistRequestKey(this.__context.Request, requestKey);

                                if (!esixtRequestKey)
                                {
                                    requestKey = info.Name + "Code";
                                    esixtRequestKey = HttpHelper.ExistRequestKey(this.__context.Request, requestKey);
                                }
                            }
                        }

                        // 存在请求键
                        if (esixtRequestKey)
                        {
                            #region
                            // 请求参数 / 表单参数
                            string requestValue = this.GetRequestValue<string>(requestKey, null);
                            //if (requestValue != null) // 默认以"-"开始的为提示信息
                            //{
                            //    if (requestValue.StartsWith("-"))
                            //        requestValue = null;
                            //}

                            // 存在外部处理方法，且外部要求终止fill填充操作
                            if (formatValue != null && formatValue(obj, info.Name, requestValue))
                                continue;

                            if (info.CanWrite && info.Name.ToUpper() != "ID") // ID无论什么情况下，都不允许填充
                            {
                                Type trueType = info.PropertyType;
                                if (info.PropertyType.IsGenericType &&
                                    info.PropertyType.GetGenericTypeDefinition().Equals(typeof(Nullable<>))) //可空类型
                                {
                                    NullableConverter nullableConverter = new NullableConverter(info.PropertyType);
                                    trueType = nullableConverter.UnderlyingType;
                                }

                                if (trueType.IsValueType || trueType == typeof(string))
                                {
                                    info.SetValue(obj, ObjectHelper.Convert(trueType, requestValue, null), null);
                                }
                            }
                            #endregion
                        }
                        else // 不存在请求键
                        {
                            if (initValue != null)
                                initValue(obj, info.Name);
                        }
                    }
                }
            }
        }
        #endregion

        #region protected
        protected ActionResult validUser()
        {
            // 登陆超时验证
            if (this.checkTimeout &&
                this.Action != "login" &&
                this.Action != "relogin" &&
                this.Action != "logout" &&
                this.Action != "reg" &&
                ServerApplication.User == null) // 登陆、重新登陆、注销、注册 例外
            {
                // 调试日志
                ServerApplication.WriteLog("Debugging.Handler", ServerApplication.LogType.Info, string.Format("【Type】 {0}; 【Action】 {1}; 【Params】 {2}; 【Method】 {3}; 【IP】 {4}; 【Return】 {5}", this.GetType().Name, this.Action, this.__context.Request.QueryString + "&" + this.__context.Request.Form, this.HttpMethod, SystemResources.Host_Info, this.formatResult(ActionResult.Timeout)));

                return ActionResult.Timeout;
            }

            return ActionResult.OK;
        }

        #endregion

        private string PrintQueryString(HttpRequest request)
        {
            if (request == null) return null;

            string queryString = null;
            foreach (var item in request.QueryString)
            {
                queryString += string.Format("{0}={1}\r\n", item, request.QueryString[item.ToString()]);
            }

            Console.WriteLine("QueryString：");
            Console.WriteLine(queryString);

            return queryString;
        }
        private string PrintQueryForm(HttpRequest request)
        {
            if (request == null) return null;

            string queryForm = null;
            foreach (var item in request.Form)
            {
                queryForm += string.Format("{0}={1}\r\n", item, request.Form[item.ToString()]);
            }

            Console.WriteLine("QueryForm：");
            Console.WriteLine(queryForm);

            return queryForm;
        }
    }

    #region ActionStatus
    /// <summary>
    /// 枚举: Action结果的状态
    /// </summary>
    public enum ActionStatus
    {
        /// <summary>
        /// -1: 空请求 (action为空的请求)
        /// </summary>
        empty = -1,
        /// <summary>
        /// -2: 不支持的请求 (如, 功能未开放)
        /// </summary>
        notsupported = -2,
        /// <summary>
        /// -3: 未识别的请求 (服务器未定义)
        /// </summary>
        unknow = -3,
        /// <summary>
        /// -4: 数据不存在 (泛定义)
        /// </summary>
        notfound = -4,
        /// <summary>
        /// -401: 数据被删或不存在 (如, 单据已被删)
        /// </summary>
        datanotfound = -401,
        /// <summary>
        /// 不接受的请求
        /// </summary>
        unaccept = 406,
        /// <summary>
        /// 200: 成功
        /// </summary>
        ok = 200,
        /// <summary>
        /// 300: 失败
        /// </summary>
        error = 300,
        /// <summary>
        /// 401: 用户未授权
        /// </summary>
        unauthorized = 401,
        /// <summary>
        /// 404: 找不到
        /// </summary>
        error_404 = 404,
        /// <summary>
        /// 500: 服务器错误
        /// </summary>
        servererror = 500,
        /// <summary>
        /// 901: 登陆超时
        /// </summary>
        timeout = 901
    }
    #endregion

    #region ActionResult
    /// <summary>
    /// 响应请求的结果类。
    /// <para>---------------------------------</para>
    /// <para>属性：</para>
    /// <para>　　status        : 结果状态</para>
    /// <para>　　callbackType  : 回发类型</para>
    /// <para>　　forwardUrl    : 成功跳转到Url</para>
    /// </summary>
    public class ActionResult : AbsResponseJSon
    {
        /// <summary>
        /// 构造函数。status=ActionStatus.ok, message = "ok"
        /// </summary>
        public ActionResult()
        {
            this.status = ActionStatus.ok;
            this.message = "ok";
        }

        /// <summary>
        /// 提示操作是否成功
        /// </summary>
        public new ActionStatus status
        {
            get { return (ActionStatus)base.status; }
            set { base.status = (int)value; }
        }

        /// <summary>
        /// 一般用于判断操作是否成功。不建议直接赋值，赋值请考虑status属性
        /// </summary>
        public override bool ok
        {
            get { return this.status == ActionStatus.ok; }
            set { this.status = (value ? ActionStatus.ok : ActionStatus.error); }
        }

        /// <summary>
        /// 回发类型
        /// </summary>
        public string callbackType { get; set; }

        /// <summary>
        /// 成功时跳转到的Url
        /// </summary>
        public string forwardUrl { get; set; }

        public string ToString_Validform()
        {
            return new Hykon.Utility.JsonWriter()
                            .WriterElement("status", (this.status == ActionStatus.ok) ? "y" : "n")
                            .WriterElement("info", this.message)
                            .WriterElement("forwardUrl", this.forwardUrl)
                            .WriterElement("ok", this.ok.ToString().ToLower())
                            .WriterElement("extend", Hykon.Utility.JsonHelper.ToJson(this.extend))
                            .ToString();
        }

        public string ToString_DWZ()
        {
            /*
                {"statusCode":"200", "message":"操作成功", "navTabId":"navNewsLi", "forwardUrl":"", "callbackType":"closeCurrent"}
                {"statusCode":"300", "message":"操作失败"}
                {"statusCode":"301", "message":"会话超时"}
            */
            string statusCode = "200";
            switch (this.status)
            {
                case ActionStatus.ok:
                    statusCode = "200"; // 操作成功
                    break;
                case ActionStatus.timeout:
                    statusCode = "301"; // 会话超时
                    break;
                default:
                    statusCode = "300"; // 操作失败
                    break;
            }

            return new Hykon.Utility.JsonWriter()
                                        .WriterElement("statusCode", statusCode)
                                        .WriterElement("message", this.message)
                                        .WriterElement("navTabId", null)
                                        .WriterElement("rel", null)
                                        .WriterElement("callbackType", this.callbackType)
                                        .WriterElement("forwardUrl", this.forwardUrl)
                                        .WriterElement("ok", this.ok.ToString().ToLower())
                                        .WriterElement("extend", Hykon.Utility.JsonHelper.ToJson(this.extend))
                                        .ToString();
        }

        /// <summary>
        /// 错误
        /// </summary>
        /// <param name="error">错误信息</param>
        /// <returns></returns>
        public static ActionResult Error(string error)
        {
            return new Action.ActionResult
            {
                status = Action.ActionStatus.error,
                message = error,
            };
        }
        /// <summary>
        /// 错误
        /// </summary>
        /// <param name="status">错误状态</param>
        /// <param name="error">错误信息</param>
        /// <returns></returns>
        public static ActionResult Error(ActionStatus status, string error)
        {
            return new Action.ActionResult
            {
                status = status,
                message = error,
            };
        }
        /// <summary>
        /// 错误
        /// </summary>
        /// <param name="ex">异常信息</param>
        /// <returns></returns>
        public static ActionResult Error(Exception ex)
        {
            return new Action.ActionResult
            {
                status = Action.ActionStatus.error,
                message = ex != null ? ex.Message : string.Empty,
            };
        }

        /// <summary>
        /// 成功
        /// </summary>
        /// <param name="info">消息</param>
        /// <returns></returns>
        public static ActionResult Succ(string info)
        {
            return new Action.ActionResult
            {
                status = Action.ActionStatus.ok,
                message = info,
            };
        }

        #region 预定义

        /// <summary>
        /// OK
        /// </summary>
        public static ActionResult OK
        {
            get
            {
                return new Action.ActionResult
                {
                    status = Action.ActionStatus.ok,
                    message = "ok",
                };
            }
        }

        /// <summary>
        /// 登陆超时: 901
        /// </summary>
        public static ActionResult Timeout
        {
            get
            {
                return new Action.ActionResult
                {
                    status = Action.ActionStatus.timeout,
                    message = "登录超时，请重新登录！",
                };
            }
        }

        /// <summary>
        /// 用户未授权
        /// </summary>
        public static ActionResult UnAuthorized
        {
            get
            {
                return new Action.ActionResult
                {
                    status = Action.ActionStatus.unauthorized,
                    message = "用户未授权！",
                };
            }
        }

        /// <summary>
        /// 未指明操作的请求
        /// </summary>
        public static ActionResult Empty
        {
            get
            {
                return new ActionResult
                {
                    status = ActionStatus.empty,
                    message = "未指明操作的请求。"
                };
            }
        }

        /// <summary>
        /// 服务器未识别的请求
        /// </summary>
        public static ActionResult Unknow
        {
            get
            {
                return new ActionResult
                {
                    status = ActionStatus.unknow,
                    message = "服务器未识别的请求。"
                };
            }
        }

        /// <summary>
        /// 服务器未识别的请求
        /// </summary>
        public static ActionResult NotSupported
        {
            get
            {
                return new ActionResult
                {
                    status = ActionStatus.notsupported,
                    message = "服务器不支持的请求。"
                };
            }
        }

        #endregion
    }
    #endregion

    #region ActionResultPacket<T>
    /// <summary>
    /// 响应请求的数据包类（data属性保存数据包信息）
    /// </summary>
    /// <typeparam name="T">数据包data的类型。如 Customer / Customer[]，作为数组时，代表包中有多个数据</typeparam>
    public class ActionResultPacket<T> : ActionResult
    {
        /// <summary>
        /// 构造函数。status=ActionStatus.ok; message = "ok"
        /// </summary>
        public ActionResultPacket()
            : base()
        {
            this.pageNum = 0;
            this.pageSize = 20;
            this.totalPages = 0;
            this.totalRecords = 0;
        }

        #region 分页参数
        /// <summary>
        /// 分页参数，页码。从1开始，无数据时为0
        /// </summary>
        public int pageNum { get; set; }
        /// <summary>
        /// 分页参数，每页记录数。
        /// </summary>
        public int pageSize { get; set; }
        /// <summary>
        /// 分页参数，总页数。
        /// </summary>
        public int totalPages { get; set; }
        /// <summary>
        /// 分页参数，总记录数。
        /// </summary>
        public int totalRecords { get; set; }
        #endregion

        /// <summary>
        /// 数据包。如 Customer / Customer[]，作为数组时，代表包中有多个数据
        /// </summary>
        public T data { get; set; }

        /// <summary>
        /// 判定数据包是否有返回值。set访问器无效
        /// </summary>
        public bool hasData
        {
            get
            {
                if (this.ok && this.data != null)
                    return (this.data is IList) ? (this.data as IList).Count > 0 : true; // 数组时，元素数需大于0

                return false;
            }
            set { throw new NotSupportedException("set访问器无效。"); }
        }

        /// <summary>
        /// 添加分页属性
        /// </summary>
        /// <param name="pageParam"></param>
        public void addExtend(PageParam pageParam)
        {
            if (pageParam != null)
            {
                this.addExtend("pageNum", pageParam.PageNum);
                this.addExtend("pageSize", pageParam.PageSize);
                this.addExtend("totalPages", pageParam.TotalPages);
                this.addExtend("totalRecords", pageParam.TotalRecords);
            }
        }
        /// <summary>
        /// 添加时间戳最大/小值、排序最大/小值
        /// </summary>
        /// <param name="minTimeStamp"></param>
        /// <param name="maxTimeStamp"></param>
        /// <param name="minOrderValue"></param>
        /// <param name="maxOrderValue"></param>
        public void addExtend(string minTimeStamp, string maxTimeStamp, int minOrderValue, int maxOrderValue)
        {
            this.addExtend("minTimeStamp", minTimeStamp);
            this.addExtend("maxTimeStamp", maxTimeStamp);
            this.addExtend("minOrderValue", minOrderValue);
            this.addExtend("maxOrderValue", maxOrderValue);
        }
    }
    #endregion
}